package net.vsame.url2sql.web;

import java.io.IOException;
import java.util.Arrays;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.vsame.url2sql.helper.Url2SqlContext;
import net.vsame.url2sql.helper.WebHelper;
import net.vsame.url2sql.url.UrlConfig;
import net.vsame.url2sql.url.UrlMapping;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Url2SqlFilter implements Filter {
	
	private static Log LOG = LogFactory.getLog(Url2SqlFilter.class);
	private static String encoding = "utf-8";
	private static boolean enabledJsonp = true;

    public Url2SqlFilter() {
    }

	public void destroy() {
	}

	public void doFilter(ServletRequest _req, ServletResponse _resp, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) _req;
		HttpServletResponse response = (HttpServletResponse) _resp;
		// 设置编码
		request.setCharacterEncoding(encoding);
		response.setCharacterEncoding(encoding);
		try{
			WebHelper.init(request, response);
			boolean[] isHandled = new boolean[]{false};
			handel(request.getRequestURI().substring(request.getContextPath().length()), request, response, isHandled);
			
			if(!isHandled[0]){
				//WebHelper中的request, response可以包装 
				chain.doFilter(WebHelper.getContext().getRequest(), WebHelper.getContext().getResponse());
			}
		}finally{
			WebHelper.remove();
		}
	}
	
	private Url2SqlContext getContext(String requestURI){
		
		String[] urlNodes = requestURI.split("/");
		if(urlNodes.length==0){
			return null;
		}
		String last = urlNodes[urlNodes.length-1];
		String ext = null;
		String[] extensionNames = new String[]{".json", ".jsonp"};
		for(String s : extensionNames){
			if(last.endsWith(s)){
				ext = s;
			}
		}
		if(!last.contains(".")){
			ext = "";
		}
		if(ext == null){
			return null; //不符合扩展名
		}
		
		//寻找Action
		UrlMapping mapping = UrlMapping.getMapping();
		StringBuffer sb = new StringBuffer();
		UrlConfig c = null;
		for(int i=0; i<urlNodes.length; i++){
			if("".equals(urlNodes[i])){
				continue;
			}
			
			sb.append("/").append(urlNodes[i]);
			if(c == null){
				c = mapping.getConfig(sb.toString());
			}
			if(c != null){
				sb = new StringBuffer();//记录参数
			}
		}
		if(c == null){
			return null; //没有对应Action
		}
		
		//创建上下文
		Url2SqlContext context = WebHelper.getContext();
		context.setExtensionName(ext);
		if(c != null){
			context.setRequestUrl(requestURI);
			context.setUrlConfig(c);
			String str = sb.toString();
			context.setRestfulParam(str.substring(0, str.length()-ext.length()));
		}
		return context;
	}
	
	public static void main(String[] args) {
		String[] urlNodes = "/a/b/c/d/e/f_1_2".split("/");
		System.out.println(Arrays.toString(urlNodes));
		StringBuffer sb = new StringBuffer();
		for(int i=0; i<urlNodes.length; i++){
			if("".equals(urlNodes[i])){
				continue;
			}
			sb.append("/").append(urlNodes[i]);
			if(i == 3){
				System.out.println(sb.toString());
				sb = new StringBuffer();
			}
		}
		System.out.println(sb);
		String str = "abc.json";
		System.out.println(str.substring(0, str.length()-".json".length()));
	}
	
	
	private void handel(String requestURI, HttpServletRequest request,
			HttpServletResponse response, boolean[] isHandled) {
		
		Url2SqlContext context = getContext(requestURI);
		if(context == null){
			return ;
		}
		
		//视图
		isHandled[0] = true;
	}



	public void init(FilterConfig config) throws ServletException {
		encoding = config.getInitParameter("encoding");
		// 默认编码为UTF-8
		if (encoding == null || "".equals(encoding)) {
			encoding = "UTF-8";
		}
		String jsonp = config.getInitParameter("jsonp");
		if("false".equalsIgnoreCase(jsonp)){
			enabledJsonp = false;
		}
		LOG.info("url2sql core init. encoding:" + encoding + ". jsonp="+enabledJsonp);
		
		UrlMapping.getMapping().reload(); 
	}
}
